package com.atguigu.tingshu.common.thread;

import com.atguigu.tingshu.common.zipkin.ZipkinHelper;
import com.atguigu.tingshu.common.zipkin.ZipkinTaskDecorator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.*;

/**
 * ClassName : ThreadPoolConfig
 * Package : com.atguigu.tingshu.common.thread
 * Description :
 * <p>
 * Author: LHZ
 * Create: 2025/7/22 20:12
 * Version: 1.0
 */
@Configuration
@Slf4j
public class ThreadPoolConfig {

    @Autowired
    private ZipkinHelper zipkinHelper;

    /**
     * 基于JDK（JUC）提供线程池Class
     */
    @Bean
    public Executor threadPoolExecutor(){
        //1.获取当前服务器核心数确定核心线程数
        int cpuCoreCount = Runtime.getRuntime().availableProcessors();
        int threadCount = cpuCoreCount * 2;
        //2.通过构造方法创建线程池对象
        ThreadPoolExecutor threadPoolExecutor =
                new ThreadPoolExecutor(
                        threadCount,
                        threadCount,
                        0,
                        TimeUnit.SECONDS,
                        new ArrayBlockingQueue<>(200),
                        Executors.defaultThreadFactory(),
                        new ThreadPoolExecutor.CallerRunsPolicy()
                );
        //3.可选:提交创建核心线程
        threadPoolExecutor.prestartCoreThread();
        return threadPoolExecutor;
    }


    @Bean
    public Executor threadPoolTaskExecutor(){
        int cpuCoreCount = Runtime.getRuntime().availableProcessors();
        int threadCount = cpuCoreCount * 2 +1;
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        //核心池大小
        taskExecutor.setCorePoolSize(threadCount);
        //最大线程数
        taskExecutor.setMaxPoolSize(threadCount);
        //队列长度
        taskExecutor.setQueueCapacity(300);
        //线程空闲时间
        taskExecutor.setKeepAliveSeconds(0);
        //现成前缀名称
        taskExecutor.setThreadNamePrefix("async-tingshu-Executor--");
        //该方法用来设置 线程池关闭 的时候 等待 所有任务全都完成后，再继续 销毁其他的Bean
        //这样这些异步任务的销毁就会先于数据库连接池对象的销毁
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        //任务的等待时间,如果超过这个时间还没有销毁 就强制销毁,以确保应用最后能够被关闭,而不是阻塞住
        taskExecutor.setAwaitTerminationSeconds(300);
        //线程不够用时由调用的线程执行任务
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //设置解决zipkin链路追踪不完整装饰器对象
        taskExecutor.setTaskDecorator(new ZipkinTaskDecorator(zipkinHelper));
        return taskExecutor;
    }
}